grammar cml;

cfg
   : statement_list
   ;

statement_list
   : assigned_statement+
   ;

assigned_statement
   : Identifier '=' expression ';'
   ;

expression
   : vector_expression
   | struct_expression
   | Constant
   ;

expression_list
   : expression (',' expression)*
   ;

vector_expression
   : '[' expression_list? ']'
   ;

struct_expression
   : '{' named_fild_list? '}'
   | '{' expression_list? '}'
   ;

named_fild_list
   : named_filed_expression (',' named_filed_expression)*
   ;

named_filed_expression
   : Identifier '=' expression
   ;

Identifier
   : Nondigit (Nondigit | Digit)*
   ;

Constant
   : IntegerConstant
   | FloatingConstant
   | BooleanConstant
   | StringLiteral
   ;

// fragment
// StatementEnd
//    : ';'
//    | ','
//    | EndOfLine
//    ;

// fragment
// EndOfLine
//    : '\n'
//    | '\r\n'
//    ;

fragment
SCharSequence
   : SChar+
   ;

fragment
SChar
   : ~["\\\r\n]
   | EscapeSequence
   ;

fragment
EscapeSequence
   : '\\' ['"?abfnrtv\\]
   ;

fragment
IntegerSuffix
   : 'i8'
   | 'i16'
   | 'i32'
   | 'i64'
   | 'u8'
   | 'u16'
   | 'u32'
   | 'u64'
   | 'u'
   ;

fragment
FloatingSuffix
   : 'f'
   | 'lf'
   ;

fragment
Sign
   : [+-]
   ;

fragment
Digit
   : [0-9]
   ;

fragment
Nondigit
   : [a-zA-Z_]
   ;

fragment
NonzeroDigit
   : [1-9]
   ;

fragment
OctalDigit
   : [0-7]
   ;

fragment
DigitSequence
   : Digit+
   ;

fragment
ExponentPart
   : [eE] Sign? DigitSequence
   ;

fragment
HexadecimalPrefix
   : '0' [xX]
   ;

fragment
HexadecimalDigit
   : [0-9a-fA-F]
   ;

fragment
HexadecimalConstant
   : HexadecimalPrefix HexadecimalDigit+
   ;

fragment
BinaryConstant
	: '0' [bB] [0-1]+
	;

fragment
DecimalConstant
   : NonzeroDigit Digit*
   ;

fragment
OctalConstant
   : '0' OctalDigit*
   ;

fragment
IntegerConstant
   : DecimalConstant IntegerSuffix?
   | OctalConstant IntegerSuffix?
   | HexadecimalConstant IntegerSuffix?
   | BinaryConstant
   ;

fragment
BooleanConstant
   : 'true' | 'false'
   ;

fragment
FloatingConstant
   : DecimalFloatingConstant
   ;

fragment
DecimalFloatingConstant
   : FractionalConstant ExponentPart? FloatingSuffix?
   | DigitSequence ExponentPart FloatingSuffix?
   ;

fragment
FractionalConstant
   : DigitSequence? '.' DigitSequence
   | DigitSequence '.'
   ;

StringLiteral
   : SingleLineStringLiteral
   ;

SingleLineStringLiteral
   : '"' SCharSequence? '"'
   ;

WhiteSpace
   : [ \t\r\n]+ -> skip
   ;
